package cn.yikaojiuguo.student.support.utils;

import android.app.Activity;
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.nostra13.universalimageloader.core.ImageLoader;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.json.JSONObject;
import org.xutils.DbManager;
import org.xutils.db.DbManagerImpl;
import org.xutils.ex.DbException;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import cn.yikaojiuguo.student.R;
import cn.yikaojiuguo.student.app.YiKaoApplication;
import cn.yikaojiuguo.student.bean.MessageEvent;
import cn.yikaojiuguo.student.support.simple.ArgsConstants;
import cn.yikaojiuguo.student.support.simple.UrlConstants;
import cn.yikaojiuguo.student.support.volley.Response;
import cn.yikaojiuguo.student.ui.usercenter.LoginActivity;
import de.greenrobot.event.EventBus;

/**
 * Created by cfan_yang on 2015/12/9.
 * 通用工具类
 */
public class Util {

    private static final String TAG = "Util";

    /**
     * 根据手机的分辨率从 dp 的单位 转成为 px(像素)
     */
    public static int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    /**
     * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
     */
    public static int px2dip(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + 0.5f);
    }

    /**
     * 打开软键盘，为保证新打开的页面可以键盘可以打开，默认延时200毫秒
     *
     * @param view
     */
    public static void openSoftInput(final View view) {
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            public void run() {
                InputMethodManager inputManager =
                        (InputMethodManager) view.getContext().getSystemService(Context
                                .INPUT_METHOD_SERVICE);
                inputManager.toggleSoftInput(0, InputMethodManager.SHOW_FORCED);
                inputManager.showSoftInputFromInputMethod(view.getWindowToken(), 0);
            }
        }, 200);
    }

    /**
     * 将秒转化为mm:ss的形式
     */
    public static String getFixedTime(int time) {
        long minute = time / 60;
        long second = time % 60;
        minute %= 60;
        return String.format("%02d:%02d", minute, second);
    }

    /**
     * 关闭软件键盘。
     *
     * @param activity
     */
    public static void closeSoftInput(Activity activity) {
        View view = activity.getWindow().peekDecorView();
        if (view != null) {
            InputMethodManager inputmanger = (InputMethodManager) activity.getSystemService
                    (Context.INPUT_METHOD_SERVICE);
            inputmanger.hideSoftInputFromWindow(view.getWindowToken(), 0);
        }
    }

    public static boolean isSoftInputActive(Context context) {
        InputMethodManager imm = (InputMethodManager) context.getSystemService(Context
                .INPUT_METHOD_SERVICE);
        return imm.isActive();
    }

    /**
     * 获取屏幕宽度
     *
     * @param context
     * @return
     */
    public static int getScreenWidthPixels(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics metrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(metrics);
        return metrics.widthPixels;
    }

    /**
     * 获取屏幕高度
     *
     * @param context
     * @return
     */
    public static int getScreenHeightPixels(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics metrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(metrics);
        return metrics.heightPixels;
    }

    /**
     * 点亮屏幕
     *
     * @param activity
     */
    public static void lightOn(Activity activity) {
        WindowManager.LayoutParams lp = activity.getWindow().getAttributes();
        lp.alpha = 1.0f;
        activity.getWindow().setAttributes(lp);
    }

    /**
     * 屏幕变暗
     *
     * @param activity
     */
    public static void lightOff(Activity activity) {
        WindowManager.LayoutParams lp = activity.getWindow().getAttributes();
        lp.alpha = 0.3f;
        activity.getWindow().setAttributes(lp);
    }

    /**
     * 判断是否是手机号
     *
     * @param number
     * @return
     */
    public static boolean isMoblie(String number) {
        Pattern p = Pattern.compile("^[1][3,4,5,8,7][0-9]{9}$");
        Matcher m = p.matcher(number);
        return m.matches();
    }

    /**
     * 能过进程ID
     *
     * @param pid
     * @return
     */
    public static String getProcessName(int pid) {
        ActivityManager am = (ActivityManager) YiKaoApplication.getInstance().getSystemService
                (Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> appProcessInfoList = am
                .getRunningAppProcesses();
        if (appProcessInfoList == null) {
            return "";
        }
        for (ActivityManager.RunningAppProcessInfo info : appProcessInfoList) {
            if (info.pid == pid) {
                return info.processName;
            }
        }
        return "";
    }

    /**
     * 获取应用VersionCode
     */
    public static int getVersionCode() {
        PackageInfo info = getPackageInfo();
        if (info != null) {
            return info.versionCode;
        }
        return 0;
    }

    /**
     * 获取应用VersionName
     *
     * @return
     */
    public static String getVersionName() {
        PackageInfo info = getPackageInfo();
        if (info != null) {
            return info.versionName;
        }
        return "";
    }

    /**
     * 获取包信息
     */
    private static PackageInfo getPackageInfo() {
        PackageManager pm = YiKaoApplication.getInstance().getPackageManager();
        try {
            PackageInfo info = pm.getPackageInfo(YiKaoApplication.getInstance().getPackageName(),
                    0);
            return info;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 压缩图片
     * 如果图片大小小于{@link YiKaoApplication#MAX_UPLOAD_IMG_SIZE},则不压缩。
     * 否则若是图片宽或高大于{@link YiKaoApplication#MAX_UPLOAD_IMG_DES}则将其
     * 分辨率压缩到{@link YiKaoApplication#MAX_UPLOAD_IMG_DES}以内，若图片大小依然
     * 大于{@link YiKaoApplication#MAX_UPLOAD_IMG_SIZE}，则对图片的质量进行压缩。
     *
     * @param fileInPath  要被压缩的图片路径
     * @param fileOutPath 压缩完成后保存图片的路径
     */
    public static void compressImg(final String fileInPath, final String fileOutPath) {
        File fileIn = new File(fileInPath);
        if (fileIn.length() > 1024 * YiKaoApplication.MAX_UPLOAD_IMG_SIZE) {//文件大于上限，压缩
            //压缩图片的分辨率
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeFile(fileInPath, options);
            int inSampleSize = caculateInSampleSize(options, YiKaoApplication.MAX_UPLOAD_IMG_DES,
                    YiKaoApplication.MAX_UPLOAD_IMG_DES);
            options.inSampleSize = inSampleSize;
            options.inJustDecodeBounds = false;
            //获取压缩分辨率后的Bitmap
            Bitmap redesBitmap = BitmapFactory.decodeFile(fileInPath, options);
            LogUtil.showInfoLog("size", "inSampleSize = " + options.inSampleSize);
            LogUtil.showInfoLog("size", "afterWidth = " + options.outWidth + " afterHeight = " +
                    options.outHeight);
            int quality = caculateCompressQuality(redesBitmap, YiKaoApplication
                    .MAX_UPLOAD_IMG_SIZE);
            saveBitmap2File(redesBitmap, fileOutPath, quality);
            if (redesBitmap != null && !redesBitmap.isRecycled()) {
                redesBitmap.recycle();
                redesBitmap = null;
            }
        } else {//文件不大于上限，直接复制
            if (!fileInPath.equals(fileOutPath)) {
                FileInputStream in = null;
                FileOutputStream out = null;
                try {
                    in = new FileInputStream(fileInPath);
                    out = new FileOutputStream(fileOutPath);
                    byte[] buffer = new byte[1024];
                    int len = 0;
                    while ((len = in.read(buffer)) != -1) {
                        out.write(buffer, 0, len);

                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    try {
                        out.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    /**
     * 将Bitmap保存到文件
     */
    public static void saveBitmap2File(Bitmap bitmap, String fileOutPath, int quality) {
        try {
            FileOutputStream fos = new FileOutputStream(fileOutPath);
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, fos);
            fos.flush();
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 根据需求计算samplesize,结果只是接近reqWidth,reqHeight
     */
    public static int caculateInSampleSize(BitmapFactory.Options options, int reqWidth, int
            reqHeight) {
        int width = options.outWidth;
        int height = options.outHeight;
        LogUtil.showInfoLog("size", "preWidth = " + width + " preHeight = " + height);
        int inSampleSize = 1;
        if (width > reqWidth || height > reqHeight) {
            int widthRadio = Math.round(width * 1.0f / reqWidth);
            int heightRadio = Math.round(height * 1.0f / reqHeight);
            inSampleSize = Math.max(widthRadio, heightRadio);
        }
        return inSampleSize;
    }

    /**
     * 对Bitmap进行质量压缩，得到文件大小小于reqSize的Bitmap
     */
    public static int caculateCompressQuality(Bitmap bitmap, int reqSize) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int quality = 100;
        bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
        //循环对options减10，直到大小小于reqSize
        while (baos.toByteArray().length / 1024 > reqSize) {
            baos.reset();
            quality -= 10;
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
        }
        return quality;
    }

    /**
     * 获取UUID
     */
    public static String getUUID() {
        return UUID.randomUUID().toString();
    }

    public static void clearCache() {
        new Thread() {
            @Override
            public void run() {
                ImageLoader.getInstance().clearDiskCache();
                ImageLoader.getInstance().clearMemoryCache();
                try {
                    YiKaoApplication.getCacheDbManager().close();
                } catch (DbException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                clearFile(YiKaoApplication.getCacheFilePath());
                //从新创建缓存数据库
                DbManager.DaoConfig daoConfig = new DbManager.DaoConfig();
                daoConfig.setDbName(ArgsConstants.DB_CACHE_NAME);
                daoConfig.setDbDir(new File(ArgsConstants.DB_CACHE_DIR));
                YiKaoApplication.setCacheDbManager(DbManagerImpl.getInstance(daoConfig));
                EventBus.getDefault().post(new MessageEvent(MessageEvent.MessageType
                        .REFRESH_CACHE_SIZE));
            }
        }.start();
    }

    /**
     * 清空文件,只删除文件，不删除文件夹
     */
    public static void clearFile(String filePath) {
        File clearFile = new File(filePath);

        if (clearFile.isDirectory()) {
            File[] childFile = clearFile.listFiles();
            for (File file : childFile) {
                clearFile(file.getAbsolutePath());
            }
        } else {
            clearFile.delete();
        }
    }

    public static long getFileSize(String filePath) {
        long totalSize = 0;
        File cacheFile = new File(filePath);
        if (cacheFile.isDirectory()) {
            File[] childFile = cacheFile.listFiles();
            for (File file : childFile) {
                totalSize += getFileSize(file.getAbsolutePath());
                Log.i("size", "file.length() = " + file.length());
                Log.i("size", "totalSize = " + totalSize);
            }
        } else {
            totalSize = cacheFile.length();
        }
        return totalSize;
    }

    /**
     * 拍照获取图片
     */
    public static String takePhoto(Activity activity, int requestCode) {
        Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
        intent.putExtra("return-data", false);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        File camera_file = new File(YiKaoApplication.getCacheImgPath(), Util.getUUID() + ".jpg");
        intent.putExtra("output", Uri.fromFile(camera_file));
        activity.startActivityForResult(intent, requestCode);
        return camera_file.getAbsolutePath();
    }

    /**
     * @param context   Activity
     * @param title     对话框标题
     * @param content   对话框内容
     * @param btn_text  按钮显示文字
     * @param listeners 按钮的监听器
     * @return
     */
    public static Dialog getCustomerDialog(Context context, String title, String content,
                                           String[] btn_text,
                                           List<android.view.View.OnClickListener> listeners) {
        AlertDialog.Builder builder = new AlertDialog.Builder(context, AlertDialog
                .THEME_HOLO_LIGHT);
        final AlertDialog dialog = builder.create();
        // AlertDialog dialog = new CustomerAlertDialog(context,
        // CustomerAlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
        View view = View.inflate(context, R.layout.dialog_customer, null);
        TextView tv_title = (TextView) view.findViewById(R.id.tv_title);
        TextView tv_content = (TextView) view.findViewById(R.id.tv_content);
        if (TextUtils.isEmpty(title)) {
            tv_title.setVisibility(View.GONE);
        } else {
            tv_title.setVisibility(View.VISIBLE);
            tv_title.setText(title);
        }
        tv_content.setText(content);
        LinearLayout ll_btns = (LinearLayout) view.findViewById(R.id.ll_btns);
        int i = 0;
        for (String text : btn_text) {
            Button button = new Button(context);
            button.setBackgroundResource(R.drawable.shape_customer_dialog_button);
            button.setText(text);
            button.setTextColor(0xff0179F1);

            android.view.View.OnClickListener buttonOnClickListener = null;
            try {
                android.view.View.OnClickListener onClickListener = listeners.get(i);
                button.setTag(onClickListener);
            } catch (Exception e) {
            } finally {
                buttonOnClickListener = new android.view.View.OnClickListener() {

                    @Override
                    public void onClick(View v) {
                        if (dialog != null) {
                            dialog.dismiss();
                        }
                        android.view.View.OnClickListener onClickListener = (android.view.View
                                .OnClickListener) v
                                .getTag();
                        if (onClickListener != null) {
                            onClickListener.onClick(v);
                        }

                    }
                };
            }

            button.setOnClickListener(buttonOnClickListener);
            ll_btns.addView(button);
            LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) button
                    .getLayoutParams();
            layoutParams.weight = 1;
            button.setLayoutParams(layoutParams);
            i++;
        }
        dialog.setView(view, 0, 0, 0, 0);
        return dialog;
    }

    public static void logOut() {
        RequestUtil.requestGet(UrlConstants.LOG_OUT + "&mid=" + YiKaoApplication.getUserId(), new
                Response.Listener<JSONObject>() {

            @Override
            public void onResponse(JSONObject response) {
                if (response != null && response.optBoolean("success")) {
                    finishLogOut();
                }
            }
        }, null, "log out");
    }

    /**
     * 服务器端为未登录状态时调用
     */
    public static void finishLogOut() {
        EventBus.getDefault().post(new MessageEvent(MessageEvent.MessageType.FINISH));
        YiKaoApplication.clearCacheUserInfo();
        YiKaoApplication.setAliasAndTags(YiKaoApplication.getUserId());
        Intent intent = LoginActivity.newIntent();
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        YiKaoApplication.getInstance().startActivity(intent);
    }

    /**
     * 采用httpclient发送post请求
     *
     * @param url
     * @param entity
     * @return
     */
    public static byte[] httpPost(String url, String entity) {
        if (url == null || url.length() == 0) {
            Log.e(TAG, "httpPost, url is null");
            return null;
        }

        HttpClient httpClient = getNewHttpClient();

        HttpPost httpPost = new HttpPost(url);

        try {
            httpPost.setEntity(new StringEntity(entity));
            httpPost.setHeader("Accept", "application/json");
            httpPost.setHeader("Content-type", "application/json");

            HttpResponse resp = httpClient.execute(httpPost);
            if (resp.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                Log.e(TAG, "httpGet fail, status code = " + resp.getStatusLine().getStatusCode());
                return null;
            }

            return EntityUtils.toByteArray(resp.getEntity());
        } catch (Exception e) {
            Log.e(TAG, "httpPost exception, e = " + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    private static HttpClient getNewHttpClient() {
        try {
            KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustStore.load(null, null);

            SSLSocketFactory sf = new SSLSocketFactoryEx(trustStore);
            sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

            HttpParams params = new BasicHttpParams();
            HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
            HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

            SchemeRegistry registry = new SchemeRegistry();
            registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
            registry.register(new Scheme("https", sf, 443));

            ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);

            return new DefaultHttpClient(ccm, params);
        } catch (Exception e) {
            return new DefaultHttpClient();
        }
    }

    private static class SSLSocketFactoryEx extends SSLSocketFactory {

        SSLContext sslContext = SSLContext.getInstance("TLS");

        public SSLSocketFactoryEx(KeyStore truststore) throws NoSuchAlgorithmException,
                KeyManagementException, KeyStoreException, UnrecoverableKeyException {
            super(truststore);

            TrustManager tm = new X509TrustManager() {

                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }

                @Override
                public void checkClientTrusted(X509Certificate[] chain, String authType) throws
                        java.security.cert.CertificateException {
                }

                @Override
                public void checkServerTrusted(X509Certificate[] chain, String authType) throws
                        java.security.cert.CertificateException {
                }
            };

            sslContext.init(null, new TrustManager[]{tm}, null);
        }

        @Override
        public Socket createSocket(Socket socket, String host, int port, boolean autoClose)
                throws IOException, UnknownHostException {
            return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
        }

        @Override
        public Socket createSocket() throws IOException {
            return sslContext.getSocketFactory().createSocket();
        }
    }
}
